package wzw.swing.text;

import java.util.HashMap;

import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;
import javax.swing.text.Segment;

import wzw.util.StringUtils;

/**
 * <p>BoundedJTextField定制的Document(DefaultModel)。</p>
 * @author	WUZEWEN on 2006-4-5
 * @version	1.0
 * @see		Object#equals(java.lang.Object)
 * @see		Object#hashCode()
 * @see		HashMap
 * @since	JDK1.4
 */

public class PlainBoundedDocument extends PlainDocument {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	protected InsertErrorListener errorListener;  // Unicast listener  
	protected int maxLength;
	protected int textType;
	private int scale;
	
	public PlainBoundedDocument() {   
		// Default constructor - must use setMaxLength later    
		this.maxLength = 0;  
	}  
	public PlainBoundedDocument(int maxLength) {    
		this.maxLength = maxLength;  
	}  
	
	public PlainBoundedDocument(AbstractDocument.Content content,int maxLength) {    
		super(content);    
		if (content.length() > maxLength) {      
			throw new IllegalArgumentException("Initial content larger than maximum size");    }    
		this.maxLength = maxLength;  
	}  

	//Getter and Setter for maxLength
	public void setMaxLength(int maxLength) {   
		if (getLength() > maxLength) {      
			throw new IllegalArgumentException("Current content larger than new maximum size");    }    
		this.maxLength = maxLength;  
	}
	public int getMaxLength() {    
		return maxLength;  
	}  

	//Getter and Setter for textType
	public void setTextType(int textType) {
		this.textType=textType;		
	}
	public int getTextType() {
		return textType;
	}

	//Getter and Setter for scale
	public void setScale(int scale) {
		this.scale=scale;		
	}	
	public int getScale() {
		return scale;
	}
	
	public void insertString(int offset, String str, AttributeSet a) 
				throws BadLocationException {    
		if (str == null) {      
			return;    
		}
		if ( this.maxLength<1 ) {	//这种情况不判断      
			//return;
			this.maxLength = 1000; 	
		}
		
		//根据设置的TextField类型，判断输入是否正确。
		switch (textType) {
		case 0:	//任意
			break;
		case 1:	//字母、数字组合
			if(!Character.isLetterOrDigit( str.charAt(0) )){    
				if (errorListener != null) {        
					errorListener.insertFailed(this, offset, str, a,"只能输入字母或者数字！");  
				} 
				return;
			}
			break;
		case 2:	//纯字母
			if(!Character.isLetter( str.charAt(0) )){    
				if (errorListener != null) {        
					errorListener.insertFailed(this, offset, str, a,"只能输入字母！");
				}
				return;
			}
			break;
		case 3:	//整数
			if(!Character.isDigit( str.charAt(0) )){    
				if (errorListener != null) {        
					errorListener.insertFailed(this, offset, str, a,"只能输入整数数字！");  
				}   
				return;
			}
			break;
			
		case 4:	//小数
			if(str.charAt(0)!='.' && !Character.isDigit( str.charAt(0) )){    
				if (errorListener != null) {        
					errorListener.insertFailed(this, offset, str, a,"只能输入小数数字！");  
				}   
				return;
			}
			break;

		default:
			break;
		}

		
		//计算已经输入的长度，判断输入是否超过最大长度
		// Note: be careful here - the content always has a    
		// trailing newline, which should not be counted!   
		Segment sg=new Segment();
		getContent().getChars(0,getContent().length(),sg );
		//System.out.println(sg.array);
		int count=0;
		if(sg.count == 1){	//这个是输入(按键、粘贴等)之前空白的情况，中英文都设置为1.		
			count = 1 ;
		}else{				//输入前不是空白的，已经有输入了.
			for (int i = 0; i < sg.count; i++) {
				if(sg.array[i]<128 && sg.array[i]>0){					
					count+=1;
				}else{
					count+=2;
				}			
			}
		}
		
		//System.out.println(count);
		//System.out.println("maxLength="+maxLength);
		//int capacity = maxLength + 1 - getContent().length();	//未处理中文	
		int capacity = maxLength + 1 - count ;    
		//System.out.println("capacity="+capacity);
		//System.out.println("capacity="+StringUtils.getByteLength(str));
		//System.out.println("getContent().length()="+getStringByteLength( str) );   
		if (capacity >= StringUtils.getByteLength(str)) {	//str.length()      
			// It all fits      
			super.insertString(offset, str, a);    
		} else {     
			// It doesn't all fit. Add as much as we can.      
			if (capacity > 0) {		//0	//0        
				super.insertString(offset, str.substring(0, capacity), a);      
				
			}      
			// Finally, signal an error.      
			if (errorListener != null) {        
				errorListener.insertFailed(this, offset, str, a,"输入内容过长！");  
			} 
			return;
		}  
	}  
	
	public void addInsertErrorListener(InsertErrorListener l) {    
		if (errorListener == null) {      
			errorListener = l;      
			return;    
		}    
		throw new IllegalArgumentException("InsertErrorListener already registered");  
	}  
	
	public void removeInsertErrorListener(InsertErrorListener l) {    
		if (errorListener == l) {      
			errorListener = null;          
		}  
	}

	/**
	 * 插入产生错误监听器接口
	 * @author WZWEN
	 *
	 */
	public interface InsertErrorListener {    
		public abstract void insertFailed(
				PlainBoundedDocument doc, int offset, String str, AttributeSet a, String string);  
	}


}

